import * as THREE from '../../js/threejs/build/three.module.js'
import {Lensflare, LensflareElement} from "../../js/threejs/jsm/objects/Lensflare.js";
import {LineSegments2} from "../../js/threejs/jsm/lines/LineSegments2.js";

function ViewSunlight(displayer, camera) {
  THREE.Object3D.call(this)

  this.animating = false
  this.controls = null
  let turnRate = 2 * Math.PI // turn rate in angles per second

  var sunTools = displayer.sunTools

  var isShadow = this.isShadow = displayer.config.getKey('project/renderer/shadows')

  var targetPosition = new THREE.Vector3()
  var targetSunQuaternion = new THREE.Quaternion()

  var q1 = new THREE.Quaternion()
  var q2 = new THREE.Quaternion()
  var radius = 0
  var m = new THREE.MeshLambertMaterial({color: 0x00ffff})
  displayer.signals.objectAdded.add(function (object) {
    object.traverse(function (child) {
      if (child.type !== 'AmbientLight') {
        child.receiveShadow = isShadow
        child.castShadow = isShadow
        // child.material = m
      }
    })
  })

  displayer.signals.objectAllConfiged.add(() => {
    const scope = this

    if (isShadow) {
      displayer.renderer.shadowMap.enabled = isShadow;   // 将渲染器阴影渲染的属性打开
      displayer.renderer.shadowMap.type = isShadow ? THREE.PCFShadowMap : THREE.BasicShadowMap
    }
    console.log('displayer.renderer.shadowMap.enabled', isShadow)

    setTimeout(() => {
      const directionalLight = configDirectionalLight()

      const longitude = displayer.deployConfig['latlon'].split(',')[0]
      const latitude = displayer.deployConfig['latlon'].split(',')[1]
      updateShaowBySunDegree(latitude, longitude, directionalLight)

      if (isShadow) {
        if (sun.visible) {
          setInterval(() => {
            updateShaowBySunDegree(latitude, longitude, directionalLight)
            // displayer.signals.objectFocused.dispatch(sceneGroup)
          }, 1000 * 60 * 1)
        }
      }
    }, 100)
  })

  displayer.signals.showShadow.add(() => {
    if (confirm(`您确定要${isShadow ? '关闭' : '打开'}阴影吗？`)) {
      displayer.config.setKey('project/renderer/shadows', !isShadow)
      const msg = `阴影已${isShadow ? '关闭' : '打开'}，立即刷新页面请点"确定"，"取消"稍后刷新`
      if (confirm(msg)) {
        location.reload()
      }
    }
  })

  //添加DirectionalLight，用来模拟太阳光
  const configDirectionalLight = () => {

    const sceneRadius = radius = displayer.objectBoundingRadius(sceneGroup)

    let directionalLight = displayer.scene.getObjectByName('DirectionalLight');
    if (!directionalLight) {
      directionalLight = new THREE.DirectionalLight(0xffffff, 1)
      directionalLight.name = 'DirectionalLight'
      displayer.addObject(directionalLight)
    }
    directionalLight.castShadow = true; // 将平行光产生阴影的属性打开

    const loader = new THREE.TextureLoader(); // threejs里面的加载器，用于加载图片
    // 用于模仿太阳光的图片图片,地址可以换成本地路径
    const textureFlare0 = loader.load('images/lensflare0.png');

    // 创建一个平行光源帮助器，帮助我们看到该光源的位置以及辐射范围
    if (!window.sun) {
      const sun = window.sun = new THREE.Object3D();
      sun['name'] = '太阳模拟器'
      displayer.scene.add(sun);
    }

    //设置地面不产生阴影
    // 设置平行光源的产生阴影的范围参数
    directionalLight.shadow.camera.near = 2;
    directionalLight.shadow.camera.far = 4900;
    directionalLight.shadow.camera.left = -sceneRadius;
    directionalLight.shadow.camera.right = sceneRadius;
    directionalLight.shadow.camera.top = sceneRadius;
    directionalLight.shadow.camera.bottom = -sceneRadius;
    // directionalLight.distance = sceneRadius*2;
    directionalLight.shadow.mapSize.x = sceneRadius * 2;
    directionalLight.shadow.mapSize.y = sceneRadius * 2;
    directionalLight.position.z = sceneRadius * 2;
    directionalLight.shadowCameraVisible = true
    const lensflare = new Lensflare();  // 实例化一个屏幕炫光对象
    // 加载屏幕炫光所用的图片，并且设置它的大小，距离光源的距离，和颜色。
    // 距离光源的距离的范围值为0到1之间，0为光源位置，1为屏幕位置。
    lensflare.addElement(new LensflareElement(textureFlare0, 512, 0, directionalLight.color));
    directionalLight.add(lensflare); // 将屏幕炫光添加进平行光里，这样屏幕炫光的位置就是平行光源的位置，并且也加到了场景中

    sun.add(directionalLight); // 将平行光源添加到点光源里
    sun.rotation.x = sunTools.degToRad(-70)

    return directionalLight
  }

  this.h = 8
  /**
   * @description:  根据地点纬度，时间来算出太阳高度角和方位角
   * @params:
   * @params:
   * @return:
   * @example:
   */
  const updateShaowBySunDegree = (latitude, longitude, directionalLight) => {

    // 获取当前时间
    let date = new Date()
    let year = date.getFullYear()
    let month = date.getMonth()
    let day = date.getDate()
    // let hour = this.h++;
    // if (this.h === 17) this.h = 8
    let hour = date.getHours()
    console.log('hour >>>> ', hour)
    let mim = date.getMinutes()
    let second = date.getSeconds()

    // 获取儒略日
    let jd = sunTools.getJulianDay(year, month + 1, day)
    console.log('获取儒略日', jd)

    // 时区
    let tz = 8

    // 今天已过了多少分钟
    let tl = sunTools.getLocalTime(hour, mim, second)

    // 使用时间、时区修正的分钟数
    let t = jd + tl / 1440.0 - tz / 24.0
    console.log('今天已过了多少分钟', t)

    // 世纪数
    t = sunTools.calcTimeJulianCent(t)
    console.log('世纪数', t)

    const solarAzimuth = sunTools.calcazimuth(t, tl, latitude, longitude, tz, 180)
    const solarAltitude = sunTools.calcelevation(t, tl, latitude, longitude, tz)
    console.log('高度角', solarAltitude) // 高度角
    console.log('方位角', solarAzimuth) // 方位角

    console.log(sun)
    // 如果太阳高度角为负数则关闭阴影效果
    if (solarAltitude < 0) {
      directionalLight.castShadow = false;  // 平行光
      directionalLight.intensity = 0
      sun.visible = false
    } else {
      directionalLight.intensity = 1;
      directionalLight.castShadow = true;
      sun.visible = true
    }

    targetSunQuaternion.setFromEuler(new THREE.Euler(sunTools.degToRad(-solarAltitude), sunTools.degToRad(-solarAzimuth), 0))
    // sun.rotation.x = sunTools.degToRad(-solarAltitude);  // 太阳高度角
    // sun.rotation.y = sunTools.degToRad(-solarAzimuth);   // 太阳方位角 弧度
    console.log(targetSunQuaternion)

    this.animating = true
  }

  this.render = function (renderer) {
    this.quaternion.copy(displayer.camera.quaternion).inverse()
    this.updateMatrixWorld()

    renderer.clearDepth()
    renderer.render(this, camera)
  }

  this.update = function (delta) {
    console.log('sunlinght.update ...')
    let step = delta
    console.log(sun.quaternion)
    console.log(targetSunQuaternion)

    sun.quaternion.rotateTowards(targetSunQuaternion, step)
    // displayer.signals.objectFocused.dispatch(sceneGroup)

    console.log(sun.quaternion.angleTo(targetSunQuaternion))
    const angleTo = sun.quaternion.angleTo(targetSunQuaternion);
    if (angleTo <= 0.01) {
      this.animating = false
    }
  }
}

ViewSunlight.prototype = Object.assign(Object.create(THREE.Object3D.prototype), {
  constructor: ViewSunlight, isViewSunlight: true,
})

export {ViewSunlight}
